﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using BasicFrameworkDemo.IDAL;
using BasicFrameworkDemo.Model;
using BasicFrameworkDemo.Utility;
using Castle.DynamicProxy;

namespace BasicFrameworkDemo.OperationLog
{
    class CommonOperationLog : IOperationLog
    {
        private readonly IRepository<OperationLogEntity> operationLog;

        public CommonOperationLog(IRepository<OperationLogEntity> operationLog)
        {
            this.operationLog = operationLog;
        }

        public void WriteLog(IInvocation invocation, OperationLogType operationLogType)
        {
            var method = invocation.Method;
            var arguments = invocation.Arguments;
            var returnValue = invocation.ReturnValue;

            var operationLogEntity = this.GetOperationLog(method, arguments, returnValue);
            operationLogEntity.Description = operationLogType.ToString() + "," + method.Name;

            operationLogEntity.Description.WriteLog(Log4NetType.Debug);
            operationLog.Save(operationLogEntity);
        }

        public void ClearLog()
        {
            operationLog.FindIQueryByHql("delete from OperationLogEntity").ExecuteUpdate();
        }

        public bool ExistLog()
        {
            var exist = operationLog.EntityQueryable.Any(p => p.Id != null);
            return exist;
        }

        private OperationLogEntity GetOperationLog(MethodInfo method, IEnumerable<object> arguments, object returnValue)
        {
            var parameters = arguments.Select(p => p as BaseRequest).Where(p => p != null).Select(argument => argument.Serialize()).FirstOrDefault();

            var operationLogEntity = new OperationLogEntity
                                   {
                                       Operation = method.DeclaringType+"."+method.Name,
                                       Description = method.Name + "," + parameters.Serialize(),
                                       Data = returnValue.Serialize(),
                                   };

            return operationLogEntity;
        }
    }
}
